package net.wanglu.www.zzz.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import opennlp.tools.coref.mention.JWNLDictionary;

import org.tartarus.snowball.ext.porterStemmer;

import edu.stanford.nlp.dcoref.CorefChain;
import edu.stanford.nlp.dcoref.CorefCoreAnnotations.CorefChainAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.NamedEntityTagAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.PartOfSpeechAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.TextAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.parser.lexparser.LexicalizedParser;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.DeterministicCorefAnnotator;
import edu.stanford.nlp.pipeline.ParserAnnotatorUtils;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.SemanticGraphCoreAnnotations.CollapsedDependenciesAnnotation;
import edu.stanford.nlp.trees.GrammaticalStructure;
import edu.stanford.nlp.trees.GrammaticalStructureFactory;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeGraph;
import edu.stanford.nlp.trees.TypedDependency;
import edu.stanford.nlp.util.CoreMap;

public class WangluNLPUtils {

	static porterStemmer stemmer = null;	
	public static String stem(String word) {
		if ( stemmer == null) {
			stemmer = new porterStemmer();
		}
		stemmer.setCurrent(word);
		stemmer.stem();
		return stemmer.getCurrent();
	}
	
	public static String lemmatization(String word, String tag) throws Exception {
		JWNLDictionary jd = OpenNLPUtils.getJWNLDictionary();
		String[] lemmaArray = jd.getLemmas(word, tag);
		if ( lemmaArray.length < 1) return null;
		return lemmaArray[0];
	}
	
	public static Object sentencePreprocess(Object...objects) throws Exception {
		// TODO Auto-generated method stub
		String sentence0 = (String) objects[0];
		
		StanfordCoreNLP pipeline = StanfordUtils.getStanfordCoreNLP();
		Annotation annotation = new Annotation(sentence0);
		pipeline.annotate(annotation);
		
		List<CoreMap> sentences = annotation.get(SentencesAnnotation.class);
		CoreMap sentence = sentences.get(0);
		LexicalizedParser lp = StanfordUtils.getLexicalizedParser();
		Tree root = lp.parse(sentence0);
		GrammaticalStructureFactory gsf = StanfordUtils
				.getGrammaticalStructureFactory();
		ParserAnnotatorUtils.fillInParseAnnotations(false, true, gsf, sentence, root);

		ArrayList<String> words = new ArrayList<String>(256);
		ArrayList<String> tags = new ArrayList<String>(256);
		ArrayList<String> ners = new ArrayList<String>(256);
		for (CoreLabel token : sentence.get(TokensAnnotation.class)) {

			String word = token.get(TextAnnotation.class);
			words.add(word);

			String pos = token.get(PartOfSpeechAnnotation.class);
			tags.add(pos);
			
			String ne = token.get(NamedEntityTagAnnotation.class);
			ners.add(ne);
		}
		
		ArrayList<TaggedWord> twl = root.taggedYield();
		
		GrammaticalStructure gs = gsf.newGrammaticalStructure(root);
		Collection<TypedDependency> tdl = gs.typedDependencies();
		
		SemanticGraph dependencies = sentence
				.get(CollapsedDependenciesAnnotation.class);
		
		DeterministicCorefAnnotator corefAnnotator = StanfordUtils.getCorefAnnotator();
		corefAnnotator.annotate(annotation);
		Map<Integer, CorefChain> coreChains = annotation.get(CorefChainAnnotation.class);
		
		HashMap<String, Object> preprocessData = new HashMap<String, Object>(4);
		preprocessData.put("sentence", sentence0);
		preprocessData.put("words", words);
		preprocessData.put("tags", tags);
		preprocessData.put("ners", ners);
		preprocessData.put("root", root);
		preprocessData.put("treeGraph", new TreeGraph(root));
		preprocessData.put("twl", twl);
		preprocessData.put("gs", gs);
		preprocessData.put("tdl", tdl);
		preprocessData.put("dependencies", dependencies);
		preprocessData.put("coreChains", coreChains);
		return preprocessData;
	}
}
